"""
API客户端类，封装SiliconFlow API调用
"""

import json
import time
import base64
from typing import Dict, List, Optional, Union, Any
from pathlib import Path
import requests
from loguru import logger

from ..config import APIConfig


class APIClient:
    """SiliconFlow API客户端"""
    
    def __init__(self, config: APIConfig):
        self.config = config
        self.session = requests.Session()
        self.session.headers.update({
            "Authorization": f"Bearer {config.api_key}",
            "Content-Type": "application/json"
        })
    
    def _make_request(self, data: Dict[str, Any], retries: int = None) -> Dict[str, Any]:
        """发送API请求"""
        if retries is None:
            retries = self.config.max_retries
        
        # 调试信息：记录请求详情
        logger.debug(f"🔄 API请求开始:")
        logger.debug(f"   URL: {self.config.base_url}")
        logger.debug(f"   Model: {data.get('model', 'unknown')}")
        logger.debug(f"   Messages count: {len(data.get('messages', []))}")
        
        # 记录请求内容（但不记录图像数据）
        debug_data = data.copy()
        if 'messages' in debug_data:
            debug_messages = []
            for msg in debug_data['messages']:
                if isinstance(msg.get('content'), list):
                    # 处理包含图像的消息
                    debug_content = []
                    for item in msg['content']:
                        if item.get('type') == 'image_url':
                            debug_content.append({"type": "image_url", "image_url": {"url": "[BASE64_IMAGE_DATA]"}})
                        else:
                            debug_content.append(item)
                    debug_messages.append({**msg, 'content': debug_content})
                else:
                    debug_messages.append(msg)
            debug_data['messages'] = debug_messages
        
        logger.debug(f"   Request data: {json.dumps(debug_data, ensure_ascii=False, indent=2)}")
            
        for attempt in range(retries + 1):
            try:
                logger.debug(f"🚀 发送API请求 (尝试 {attempt + 1}/{retries + 1})")
                
                response = self.session.post(
                    self.config.base_url,
                    json=data,
                    timeout=self.config.timeout
                )
                
                logger.debug(f"📥 收到响应:")
                logger.debug(f"   Status Code: {response.status_code}")
                logger.debug(f"   Headers: {dict(response.headers)}")
                
                # 记录响应内容
                try:
                    response_json = response.json()
                    logger.debug(f"   Response JSON: {json.dumps(response_json, ensure_ascii=False, indent=2)}")
                except:
                    logger.debug(f"   Response Text: {response.text}")
                
                response.raise_for_status()
                
                logger.debug(f"✅ API请求成功")
                return response_json
                
            except requests.exceptions.Timeout as e:
                logger.warning(f"⏰ API请求超时 (尝试 {attempt + 1}/{retries + 1}): {e}")
                if attempt == retries:
                    logger.error(f"❌ API请求最终超时失败")
                    raise
                # 超时时使用更长的等待时间
                wait_time = min(30, 5 * (2 ** attempt))
                logger.info(f"⏳ 等待 {wait_time} 秒后重试...")
                time.sleep(wait_time)
                
            except requests.exceptions.RequestException as e:
                logger.warning(f"🚫 API请求失败 (尝试 {attempt + 1}/{retries + 1}): {e}")
                
                # 记录详细的错误信息
                if hasattr(e, 'response') and e.response is not None:
                    logger.error(f"   Error Status Code: {e.response.status_code}")
                    logger.error(f"   Error Response: {e.response.text}")
                
                if attempt == retries:
                    logger.error(f"❌ API请求最终失败")
                    raise
                # 其他错误使用较短的等待时间
                wait_time = min(10, 2 ** attempt)
                logger.info(f"⏳ 等待 {wait_time} 秒后重试...")
                time.sleep(wait_time)
    
    def chat_completion(
        self,
        messages: List[Dict[str, str]],
        model: Optional[str] = None,
        temperature: float = 0.7,
        max_tokens: Optional[int] = None,
        **kwargs
    ) -> str:
        """文本聊天完成"""
        data = {
            "model": model or self.config.text_model,
            "messages": messages,
            "temperature": temperature,
            **kwargs
        }
        
        if max_tokens:
            data["max_tokens"] = max_tokens
            
        try:
            response = self._make_request(data)
            return response["choices"][0]["message"]["content"]
        except Exception as e:
            logger.error(f"文本API调用失败: {e}")
            raise
    
    def vision_completion(
        self,
        text_prompt: str,
        image_path: Optional[str] = None,
        image_base64: Optional[str] = None,
        model: Optional[str] = None,
        system_prompt: Optional[str] = None,
        **kwargs
    ) -> str:
        """视觉模型完成"""
        if not image_path and not image_base64:
            raise ValueError("必须提供图片路径或base64编码")
            
        # 准备图片数据
        if image_path and not image_base64:
            image_base64 = self._encode_image(image_path)
            
        messages = []
        
        # 添加系统提示（如果提供）
        if system_prompt:
            messages.append({
                "role": "system",
                "content": system_prompt
            })
            
        # 添加用户消息（包含文本和图片）
        messages.append({
            "role": "user",
            "content": [
                {"type": "text", "text": text_prompt},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/jpeg;base64,{image_base64}"
                    }
                }
            ]
        })
        
        data = {
            "model": model or self.config.vision_model,
            "messages": messages,
            **kwargs
        }
        
        # GLM-4.1V-9B-Thinking模型不需要特殊参数
        # 移除enable_thinking等参数，因为该模型不支持
        
        try:
            response = self._make_request(data)
            return response["choices"][0]["message"]["content"]
        except Exception as e:
            logger.error(f"视觉API调用失败: {e}")
            raise
    
    def _encode_image(self, image_path: str) -> str:
        """将图片编码为base64"""
        try:
            with open(image_path, "rb") as image_file:
                return base64.b64encode(image_file.read()).decode('utf-8')
        except Exception as e:
            logger.error(f"图片编码失败 {image_path}: {e}")
            raise
    
    def batch_completion(
        self,
        requests_data: List[Dict[str, Any]],
        max_concurrent: int = 5
    ) -> List[str]:
        """批量处理请求"""
        import concurrent.futures
        import threading
        
        results = [None] * len(requests_data)
        semaphore = threading.Semaphore(max_concurrent)
        
        def process_request(index: int, request_data: Dict[str, Any]) -> None:
            with semaphore:
                try:
                    if "image_path" in request_data or "image_base64" in request_data:
                        # 视觉请求
                        result = self.vision_completion(**request_data)
                    else:
                        # 文本请求
                        result = self.chat_completion(**request_data)
                    results[index] = result
                except Exception as e:
                    logger.error(f"批量请求 {index} 失败: {e}")
                    results[index] = f"错误: {str(e)}"
        
        with concurrent.futures.ThreadPoolExecutor(max_workers=max_concurrent) as executor:
            futures = [
                executor.submit(process_request, i, req)
                for i, req in enumerate(requests_data)
            ]
            concurrent.futures.wait(futures)
        
        return results
    
    def health_check(self) -> bool:
        """健康检查"""
        try:
            response = self.chat_completion(
                messages=[{"role": "user", "content": "Hello"}],
                max_tokens=10
            )
            return bool(response)
        except Exception as e:
            logger.error(f"API健康检查失败: {e}")
            return False